package com.yanqu.road.logic.cross;

import com.yanqu.road.entity.rank.ServerRank;
import com.yanqu.road.logic.bussiness.rank.RankBussiness;
import com.yanqu.road.logic.pb.CrossActivityPb;
import com.yanqu.road.logic.sort.ServerRankSort;
import com.yanqu.road.pb.cross.activity.CrossActivityProto;

import java.util.*;
import java.util.stream.IntStream;

public class CrossActivityServerRankListModel {

    private boolean isNeedSync = false;

    private ServerRankSort sorter;

    private boolean isUpdate = false;


    private LinkedList<ServerRank> rankList;

    private int activityId;

    private CrossActivityProto.CrossActivityServerRankListMsg.Builder serverRankListMsg;

    public CrossActivityServerRankListModel(int activityId) {
        sorter = new ServerRankSort();
        rankList = new LinkedList<>();
        serverRankListMsg = CrossActivityProto.CrossActivityServerRankListMsg.newBuilder();
        this.activityId = activityId;
    }

    public int getActivityId() {
        return activityId;
    }

    public boolean isNeedSync() {
        return isNeedSync;
    }

    public void setNeedSync(boolean needSync) {
        isNeedSync = needSync;
    }

    public CrossActivityProto.CrossActivityServerRankListMsg.Builder getServerRankListMsg() {
        return serverRankListMsg.clone();
    }

    public void setRankList(LinkedList<ServerRank> serverRankList) {
        synchronized (this) {
            this.rankList = new LinkedList<>(serverRankList);
            checkListValid();      //校验一下数组
            this.rankList.sort(sorter);
            initRankMsg();
        }
    }

    /**
     * 校验数组，去掉重复数据
     */
    private void checkListValid(){
        List<Integer> needRemoveList = new ArrayList<>();
        List<Long> hasServerIdList = new ArrayList<>();
        for (int i = 0; i < rankList.size(); i++) {
            ServerRank serverRank = rankList.get(i);
            if(!hasServerIdList.contains(serverRank.getServerId())){
                hasServerIdList.add(serverRank.getServerId());
            }else {
                needRemoveList.add(i);
            }
        }
        if(needRemoveList.size() > 0){
            Collections.sort(needRemoveList);
            Collections.reverse(needRemoveList);
            for (int index : needRemoveList) {
                rankList.remove(index);
            }
        }
    }

    private void initRankMsg() {
        serverRankListMsg = CrossActivityPb.parseCrossActivityServerRankListMsg(rankList);
    }

    public int getMyRank(long serverId) {
        synchronized (this) {
            OptionalInt result = IntStream.range(0, rankList.size()).filter(i -> rankList.get(i).getServerId() == serverId).findFirst();
            if (result.isPresent()) {
                return result.getAsInt() + 1;
            }
            return -1;
        }
    }

    public ServerRank getMyRankInfo(long serverId) {
        synchronized (this) {
            OptionalInt result = IntStream.range(0, rankList.size()).filter(i -> rankList.get(i).getServerId() == serverId).findFirst();
            if (result.isPresent()) {
                return rankList.get(result.getAsInt());
            }
            return null;
        }
    }

    /**
     * 添加到排行
     */
    public void rankChange(ServerRank serverRank) {
        synchronized (this) {
            if (!rankList.stream().anyMatch(predicate -> predicate.getServerId() == serverRank.getServerId())) {
                rankList.add(serverRank);
            } else {
                rankList.forEach(action -> {
                    if (action.getServerId() == serverRank.getServerId()) {
                        action.setValue(serverRank.getValue());
                    }
                });
            }
            rankList.sort(sorter);
            initRankMsg();
            isNeedSync = true;
            isUpdate = true;
        }
    }


    public void saveRelation(){
        LinkedList<ServerRank> serverList;
        synchronized (this) {
            if (!isUpdate) {
                return;
            }
            serverList = new LinkedList<>(rankList);
            isUpdate = false;
        }
        RankBussiness.updateCrossServerRankList(activityId,serverList);
    }
}
